/**
 * JZ UnoCSS - uvue 专用原子化CSS插件
 * 专门支持 uni-app x (.uvue) 文件
 * @version 1.1.0
 * @author jz
 */

"use strict";

// 导入子模块
import { utils } from './js/utils/utils.js';
import { defaultColors } from './js/utils/colors.js';
import { generateCSS } from './js/core/generator.js';
import { processCode } from './js/processors/processor.js';
import { CSSWatcher, cssWatcher, cssWatcherUtils } from './js/watchers/css-watcher.js';
import { 
    core, 
    flex, 
    media, 
    unocss, 
    pseudo, 
    sketch, 
    border 
} from './js/config/presets.js';

// 导入新的拆分模块
import { 
    updateMainCSS, 
    generateMinimalCSS, 
    generateBasicCSS, 
    generateFallbackCSS, 
    updateCSSFile 
} from './js/watchers/css-updater.js';
import { 
    scanDirectory, 
    extractClassNamesFromCode, 
    detectProjectRoot, 
    scanProjectFiles 
} from './js/watchers/file-scanner.js';
import { 
    extractClassNamesWithContext 
} from './js/processors/processor.js';
import { 
    generateUnifiedCSSRules, 
    generateUnifiedCSS,
    processGradientClasses,
    processTransformClasses,
    generateCSSRulesWithEncoding,
    generateCSSRules
} from './js/core/unified-css-generator.js';
import { 
    isValidUnoClass, 
    debounce, 
    throttle, 
    deepMerge, 
    formatFileSize, 
    fileExists, 
    readFileContent, 
    writeFileContent 
} from './js/utils/helpers.js';
import { 
    checkAndAutoGenerateCSS, 
    autoGenerateAccurateCSS, 
    generateCSSForESModule 
} from './js/generators/css-auto-generator.js';

// 全局文件变化记录
const fileChangeHistory = new Map();
let globalForceReload = false;

// 全局CSS缓存，避免重复生成
const globalCSSCache = new Map();

// 初始化状态标记
let isInitialized = false;

// CSS写入锁定机制
let cssWriteLock = false;

// 临时调试函数：手动触发渐变CSS生成和写入
function debugGradientCSS() {
    try {
        const testCode = `
        <view class="bg-gradient-to-br from-indigo-500 to-purple-600 pt-20 pr-8 pb-24 pl-8">
            测试渐变背景
        </view>
        `;
        
        console.log(`[JZ UnoCSS Debug] 开始测试渐变CSS生成...`);
        const result = generateAndUpdateCSS(testCode, 'debug-test.uvue');
        console.log(`[JZ UnoCSS Debug] 渐变CSS生成结果: ${result ? '成功' : '失败'}`);
        
        return result;
    } catch (error) {
        console.error('[JZ UnoCSS Debug] 调试过程出错:', error.message);
        return false;
    }
}

// 暴露调试函数到全局
if (typeof window !== 'undefined') {
    window.debugJzUnocssGradient = debugGradientCSS;
} else if (typeof global !== 'undefined') {
    global.debugJzUnocssGradient = debugGradientCSS;
}

// 按照详细编码规则生成CSS - 支持渐变组合
function generateAndUpdateCSS(code, filePath, forceRegenerate = false) {
    // 检查锁定状态
    if (cssWriteLock) {
        return false;
    }
    
    try {
        cssWriteLock = true; // 加锁
        
        // 检查输入参数
        if (!code || typeof code !== 'string') {
            return false;
        }
        
        // 提取类名和组合信息
        const result = extractClassNamesWithContext(code);
        
        // 检查返回结果
        if (!result || typeof result !== 'object') {
            return false;
        }
        
        const { allClassNames, classNameGroups } = result;
        
        // 确保结果是数组
        const safeAllClassNames = Array.isArray(allClassNames) ? allClassNames : [];
        const safeClassNameGroups = Array.isArray(classNameGroups) ? classNameGroups : [];
        
        if (safeAllClassNames.length === 0) {
            return false;
        }
        
        // 只在有新类名时输出日志
        console.log(`[JZ UnoCSS] ${filePath} 发现类名:`, safeAllClassNames);
        
        // 生成CSS规则（使用统一的CSS规则生成器，传入类名分组）
        const cssRules = generateUnifiedCSS(safeAllClassNames, safeClassNameGroups, globalConfig);
        
        // 确保cssRules是数组
        if (!Array.isArray(cssRules) || cssRules.length === 0) {
            return false;
        }
        
        let newCSSContent;
        
        if (forceRegenerate) {
            // 强制重新生成模式：直接使用新规则
            newCSSContent = cssRules.join('\n\n') + '\n';
            console.log(`[JZ UnoCSS] 🔄 强制重新生成模式`);
        } else {
            // 增量更新模式：读取现有CSS并智能合并
            let existingCSS = '';
            try {
                const fs = require('fs');
                if (fs.existsSync(globalConfig.cssOutputPath)) {
                    existingCSS = fs.readFileSync(globalConfig.cssOutputPath, 'utf-8');
                }
            } catch (error) {
                // 静默处理读取错误
            }
            
            // 智能合并CSS规则
            newCSSContent = mergeCSS(existingCSS, cssRules, safeAllClassNames);
        }
        
        const writeResult = updateCSSFile(newCSSContent, globalConfig);
        
        if (writeResult) {
            console.log(`[JZ UnoCSS] ✅ CSS已更新`);
        }
        
        return writeResult;
        
    } catch (error) {
        console.error('[JZ UnoCSS] CSS生成失败:', error.message);
        return false;
    } finally {
        cssWriteLock = false; // 解锁
    }
}

/**
 * 智能合并CSS规则，避免重复和冲突
 * @param {string} existingCSS - 现有CSS内容
 * @param {string[]} newRules - 新的CSS规则数组
 * @param {string[]} classNames - 当前处理的类名
 * @returns {string} 合并后的CSS内容
 */
function mergeCSS(existingCSS, newRules, classNames) {
    try {
        // 如果没有现有CSS，直接返回新规则
        if (!existingCSS || !existingCSS.trim()) {
            return newRules.join('\n\n') + '\n';
        }
        
        // 解析现有CSS，提取已存在的类名
        const existingClassNames = new Set();
        const classRegex = /\.([a-zA-Z0-9_-]+)\s*\{/g;
        let match;
        while ((match = classRegex.exec(existingCSS)) !== null) {
            existingClassNames.add(match[1]);
        }
        
        // 只添加不存在的CSS规则
        const newRulesToAdd = [];
        for (const rule of newRules) {
            const ruleClassMatch = rule.match(/\.([a-zA-Z0-9_-]+)\s*\{/);
            if (ruleClassMatch) {
                const className = ruleClassMatch[1];
                if (!existingClassNames.has(className)) {
                    newRulesToAdd.push(rule);
                    existingClassNames.add(className);
                }
            } else {
                // 如果无法解析类名，直接添加（可能是复杂规则）
                newRulesToAdd.push(rule);
            }
        }
        
        // 如果有新规则要添加，追加到现有CSS
        if (newRulesToAdd.length > 0) {
            return existingCSS + '\n' + newRulesToAdd.join('\n\n') + '\n';
        } else {
            return existingCSS;
        }
        
    } catch (error) {
        console.warn(`[JZ UnoCSS] CSS合并失败，使用新规则:`, error.message);
        return newRules.join('\n\n') + '\n';
    }
}

// 全局配置变量
let globalConfig = {};

// 全局CSS重新生成函数 - 同时暴露到浏览器和Node.js环境
const regenerateCSS = async () => {
    try {
        // 扫描项目文件
        const uvueFiles = scanProjectFiles(['.uvue'], globalConfig.projectRoot);
        
        if (uvueFiles.length === 0) {
            return false;
        }
        
        // 提取所有类名和组合信息
        const allClassNames = new Set();
        const allClassNameGroups = [];
        for (const file of uvueFiles) {
            try {
                const fs = require('fs');
                const content = fs.readFileSync(file, 'utf-8');
                const { allClassNames: fileClassNames, classNameGroups: fileGroups } = extractClassNamesWithContext(content);
                fileClassNames.forEach(name => allClassNames.add(name));
                allClassNameGroups.push(...fileGroups);
            } catch (error) {
                console.warn(`[JZ UnoCSS] 读取文件失败 ${file}:`, error.message);
            }
        }
        
        const uniqueClassNames = Array.from(allClassNames);
        
        if (uniqueClassNames.length === 0) {
            return false;
        }
        
        // 生成CSS规则（传入类名分组）
        const cssRules = generateUnifiedCSS(uniqueClassNames, allClassNameGroups, globalConfig);
        
        // 确保cssRules是数组
        if (Array.isArray(cssRules) && cssRules.length > 0) {
            const cssContent = cssRules.join('\n\n') + '\n';
            
            console.log(`[JZ UnoCSS] regenerateCSS: 重新生成CSS文件`);
            
            const writeResult = updateCSSFile(cssContent, globalConfig);
            console.log(`[JZ UnoCSS] regenerateCSS: CSS写入结果: ${writeResult ? '成功' : '失败'}`);
            
            return writeResult;
        }
        
        return false;
    } catch (error) {
        console.error('[JZ UnoCSS] ❌ 手动重新生成出错:', error.message);
        return false;
    }
};

// 主插件函数
function jzUnocss(options = {}) {
    // 配置处理
    const config = {
        presets: options.presets || [core(), flex(), media(), pseudo(), border()],
        prefix: options.prefix || ['jz', 'uno'],
        exclude: options.exclude || ['node_modules', 'dist'],
        excludeClasses: options.excludeClasses || [],
        mode: options.mode || (process.env.NODE_ENV === 'production' ? 'production' : 'development'),
        cssOutputPath: options.cssOutputPath || 'uni_modules/jz-unocss-uvue/main.css',
        log: options.log !== false,
        h5Unit: options.h5Unit || 'rem',
        remBase: options.remBase || 16,
        theme: options.theme || {},
        // 新增：是否编译全端代码，默认为true
        compileAllPlatforms: options.compileAllPlatforms !== false,
        // 新增：项目根目录配置
        projectRoot: options.projectRoot || null  // 允许用户手动指定项目根目录
    };
    
    // 设置全局配置
    globalConfig = config;
    try {
        const path = require('path');
        console.log(`[JZ UnoCSS] 📁 绝对输出路径: ${path.resolve(config.cssOutputPath)}`);
    } catch (error) {
        console.warn('[JZ UnoCSS] 路径解析失败:', error.message);
    }

    // 项目根目录将由 file-scanner.js 的相对路径方法自动检测，无需特殊处理

    // 启动时进行完整的项目扫描和CSS生成（默认开启，无需配置）
    if (!isInitialized) {
        isInitialized = true;
        setTimeout(() => {
            console.log(`[JZ UnoCSS] 🚀 开始初始化CSS生成...`);
            
            // 项目根目录检测交给 file-scanner.js 的相对路径方法处理
            
            console.log(`[JZ UnoCSS] 📂 CSS输出路径: ${config.cssOutputPath}`);
            console.log(`[JZ UnoCSS] 🏠 最终项目根目录: ${config.projectRoot || '使用默认检测'}`);
            console.log(`[JZ UnoCSS] 🌐 编译全端代码: ${config.compileAllPlatforms ? '是' : '否'}`);
            
            try {
                // 检查CSS文件是否存在，如果不存在则创建，存在则保留
                const fs = require('fs');
                if (!fs.existsSync(config.cssOutputPath)) {
                    fs.writeFileSync(config.cssOutputPath, '/* JZ UnoCSS - 自动生成的CSS文件 */\n', 'utf-8');
                    console.log(`[JZ UnoCSS] ✅ 创建新的CSS文件`);
                } else {
                    console.log(`[JZ UnoCSS] ✅ CSS文件已存在，继续使用现有文件`);
                }
                
                // 扫描项目文件
                console.log(`[JZ UnoCSS] 🔍 开始完整文件扫描...`);
                const uvueFiles = scanProjectFiles(['.uvue'], config.projectRoot);
                
                if (uvueFiles.length === 0) {
                    console.warn(`[JZ UnoCSS] ⚠️ 未找到任何.uvue文件`);
                    return;
                }
                
                console.log(`[JZ UnoCSS] 📊 找到 ${uvueFiles.length} 个.uvue文件，开始处理...`);
                
                // 提取所有类名和组合信息
                const allClassNames = new Set();
                const allClassNameGroups = [];
                let processedFiles = 0;
                let totalClassCount = 0;
                
                for (const file of uvueFiles) {
                    try {
                        const content = fs.readFileSync(file, 'utf-8');
                        const { allClassNames: fileClassNames, classNameGroups: fileGroups } = extractClassNamesWithContext(content);
                        
                        fileClassNames.forEach(name => allClassNames.add(name));
                        allClassNameGroups.push(...fileGroups);
                        
                        totalClassCount += fileClassNames.length;
                        processedFiles++;
                        
                        console.log(`[JZ UnoCSS] 📄 ${file}: ${fileClassNames.length} 个类名`);
                        
                    } catch (error) {
                        console.warn(`[JZ UnoCSS] ❌ 处理文件失败 ${file}:`, error.message);
                    }
                }
                
                const uniqueClassNames = Array.from(allClassNames);
                
                console.log(`[JZ UnoCSS] 📈 统计信息:`);
                console.log(`[JZ UnoCSS]   - 处理文件: ${processedFiles}/${uvueFiles.length}`);
                console.log(`[JZ UnoCSS]   - 总类名数: ${totalClassCount}`);
                console.log(`[JZ UnoCSS]   - 唯一类名: ${uniqueClassNames.length}`);
                console.log(`[JZ UnoCSS]   - 类名组合: ${allClassNameGroups.length}`);
                
                if (uniqueClassNames.length === 0) {
                    console.warn(`[JZ UnoCSS] ⚠️ 未提取到任何类名`);
                    return;
                }
                
                // 生成完整的CSS
                console.log(`[JZ UnoCSS] 🎯 开始生成CSS规则...`);
                const cssRules = generateUnifiedCSS(uniqueClassNames, allClassNameGroups, globalConfig);
                
                if (!Array.isArray(cssRules) || cssRules.length === 0) {
                    console.warn(`[JZ UnoCSS] ⚠️ 未生成任何CSS规则`);
                    return;
                }
                
                // 统计生成的CSS规则
                const gradientRules = cssRules.filter(rule => rule.includes('background-image'));
                const regularRules = cssRules.filter(rule => !rule.includes('background-image'));
                
                console.log(`[JZ UnoCSS] ✅ CSS生成完成:`);
                console.log(`[JZ UnoCSS]   - 总规则数: ${cssRules.length}`);
                console.log(`[JZ UnoCSS]   - 渐变规则: ${gradientRules.length}`);
                console.log(`[JZ UnoCSS]   - 普通规则: ${regularRules.length}`);
                
                // 写入CSS文件
                const cssContent = cssRules.join('\n\n') + '\n';
                
                // 初始化时强制写入完整CSS，不使用增量合并
                console.log(`[JZ UnoCSS] 🔄 初始化模式：强制重新生成完整CSS`);
                
                // 直接写入完整CSS，不使用mergeCSS
                try {
                    const fs = require('fs');
                    const path = require('path');
                    
                    // 确保目录存在
                    const dir = path.dirname(config.cssOutputPath);
                    if (!fs.existsSync(dir)) {
                        fs.mkdirSync(dir, { recursive: true });
                    }
                    
                    // 添加CSS文件头部注释
                    const finalCSSContent = `/* JZ UnoCSS - 自动生成的CSS文件 */\n\n${cssContent}`;
                    
                    // 直接写入文件
                    fs.writeFileSync(config.cssOutputPath, finalCSSContent, 'utf-8');
                    
                    console.log(`[JZ UnoCSS] ✅ 初始化CSS写入成功`);
                    
                    // 计算文件大小
                    try {
                        const fileSize = (fs.statSync(config.cssOutputPath).size / 1024).toFixed(2);
                        console.log(`[JZ UnoCSS] 📊 文件大小: ${fileSize} KB`);
                    } catch (error) {
                        // 忽略文件大小计算错误
                    }
                    
                    console.log(`[JZ UnoCSS] 🎉 初始化完成！`);
                    
                } catch (writeError) {
                    console.error(`[JZ UnoCSS] ❌ 初始化CSS写入失败:`, writeError.message);
                }
                
            } catch (error) {
                console.error('[JZ UnoCSS] ❌ 初始化过程出错:', error.message);
                console.error('[JZ UnoCSS] 错误堆栈:', error.stack);
            }
        }, 500); // 给足够的时间让模块加载完成
    }

    return {
        name: 'jz-unocss-uvue',
        enforce: 'pre',
        // 添加客户端代码注入
        transformIndexHtml(html) {
            // 注入浏览器端的重新生成函数
            const clientScript = `
                <script>
                    (function() {
                        // 创建浏览器端的重新生成函数
                        window.jzUnocssRegenerateCSS = function() {
                            // 刷新页面以加载最新的CSS
                            window.location.reload();
                            return true;
                        };
                        
                        // 也暴露到 globalThis
                        globalThis.jzUnocssRegenerateCSS = window.jzUnocssRegenerateCSS;
                    })();
                </script>
            `;
            
            return html.replace(/<head>/, `<head>${clientScript}`);
        },
        
        // 简化的transform函数 - 核心改进
        transform(code, id) {
            // 只处理 uvue 文件
            if (!/\.uvue$/.test(id)) {
                return null;
            }
            
            // 进行类名编码转换，确保HTML中的方括号类名能匹配CSS选择器
            let transformedCode = code;
            
            // 查找所有class属性中的方括号类名并进行编码
            transformedCode = transformedCode.replace(/class\s*=\s*["']([^"']+)["']/g, (match, classString) => {
                // 分割类名
                const classNames = classString.split(/\s+/).filter(cls => cls.trim());
                
                // 对包含方括号语法的类名进行编码（只编码真正需要的）
                const encodedClassNames = classNames.map(className => {
                    // 只对包含方括号语法的类名进行编码
                    // 方括号语法示例：text-[#333], w-[50%], bg-[rgb(255,0,0)], text-[1.5rem]
                    if (/\[.*\]/.test(className)) {
                        // 导入utils模块
                        const { utils } = require('./js/utils/utils.js');
                        return utils.encodeClassNameForUvue(className);
                    }
                    return className;
                });
                
                // 重新组合类名
                const encodedClassString = encodedClassNames.join(' ');
                return match.replace(classString, encodedClassString);
            });
            
            // 禁用所有其他代码转换，只进行CSS生成
            // 避免任何可能影响模版编译的操作
            if (config.compileAllPlatforms && config.mode === 'development' && isInitialized) {
                // 异步进行CSS更新，不阻塞编译
                setTimeout(() => {
                    try {
                        generateAndUpdateCSS(code, id);
                    } catch (error) {
                        console.warn('[JZ UnoCSS] transform CSS更新失败:', error.message);
                    }
                }, 0);
            }
            
            // 返回转换后的代码
            return {
                code: transformedCode,
                map: null
            };
        },
        
        // 简化的热更新处理
        async handleHotUpdate(ctx) {
            // 检查参数
            if (!ctx || !ctx.file) {
                return;
            }
            
            if (!/\.uvue$/.test(ctx.file)) {
                return;
            }
            
            // 只在开发模式下进行热更新
            if (config.mode !== 'development' || !config.compileAllPlatforms) {
                return;
            }
            
            console.log(`[JZ UnoCSS] 热更新: ${ctx.file}`);
            
            // 简化的热更新处理：延迟执行，避免阻塞
            setTimeout(async () => {
                try {
                    // 兼容不同环境的文件读取
                    let fs;
                    try {
                        fs = require('fs');
                    } catch (e) {
                        console.warn('[JZ UnoCSS] 无法加载文件系统模块');
                        return;
                    }
                    
                    // 检查文件是否存在
                    if (!fs.existsSync(ctx.file)) {
                        return;
                    }
                    
                    const content = fs.readFileSync(ctx.file, 'utf-8');
                    
                    if (!content || typeof content !== 'string') {
                        return;
                    }
                    
                    // 异步处理CSS更新，不阻塞热更新流程
                    generateAndUpdateCSS(content, ctx.file);
                } catch (error) {
                    // 静默处理错误，不影响热更新
                    console.warn('[JZ UnoCSS] 热更新CSS处理失败:', error.message);
                }
            }, 100); // 短暂延迟，让文件更新完成
        }
    };
}

// ES6 模块导出
export default jzUnocss;
export { 
    core, 
    flex, 
    media, 
    unocss, 
    pseudo, 
    sketch, 
    border, 
    utils, 
    generateCSS,
    processCode,
    defaultColors,
    CSSWatcher,
    cssWatcher,
    cssWatcherUtils,
    // 导出新的模块函数
    updateMainCSS,
    generateMinimalCSS,
    generateBasicCSS,
    generateFallbackCSS,
    updateCSSFile,
    scanDirectory,
    extractClassNamesWithContext,
    extractClassNamesFromCode,
    detectProjectRoot,
    scanProjectFiles,
    generateUnifiedCSSRules,
    generateUnifiedCSS,
    processGradientClasses,
    processTransformClasses,
    generateCSSRulesWithEncoding,
    generateCSSRules,
    isValidUnoClass,
    debounce,
    throttle,
    deepMerge,
    formatFileSize,
    fileExists,
    readFileContent,
    writeFileContent,
    checkAndAutoGenerateCSS,
    autoGenerateAccurateCSS,
    generateCSSForESModule,
    regenerateCSS
}; 